<?php
class CartWS_Service_Order extends Ext_Services
{

    protected $_order = null;

    public function __construct( )
    {
        $this->_config = Zend_Registry::get('config');
        $this->_order = new CartWS_Model_Order();
    }

    /**
     * Devuelve la info completa de una orden a partir de un orderId, 
     * 
     * esta orden tiene que ser del usuario que la pide.
     * 
     * @param integer $userId
     * @param string $credential
     * @param integer $orderId
     * @return array
     */
    public function getFullOrderInfo( $userId, $credential, $orderId )
    {
    	try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getFullOrderInfo( $userId, $orderId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
    }
    
	/**
	 * 
	 * Devuelve la linea de zonas a partir de un  parentId. El depth mas alto es 0 
	 * 
	 * @param integer $userId
	 * @param string $credential
	 * @param integer $parentId
	 * @return mixed
	 */
	public function getZone($userId, $credential, $parentId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getZone( $parentId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Devuelve los datos de la orden
	 *  
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @return array OrderRow
	 */
	public function getOrder( $userId, $credential, $orderId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getOrder( $orderId );
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}

	/**
	 * 
	 * Retorna la orden Activa del cliente. Si no existe la crea
	 *  
	 * @param integer userId
	 * @param string Credential
	 * @param mixed $properties
	 * @return integer $orderId
	 */
	public function getActiveOrder( $userId, $credential, $properties = array() )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getActiveOrder( $userId, $properties);
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * Devuelve el costo de envio 
	 * 
	 * @param integer $userId
	 * @param string $credential
	 * @param integer $orderId
	 * @return integer 
	 */
	public function getShippingCost( $userId, $credential, $orderId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getShippingCost( $orderId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}		
		
	}
	/**
	 * 
	 * Devuelve un array con id, y descripcion de las direcciones asociadas a un usuario
	 * @param integer userId
	 * @param string Credential
	 * @param integer customerId
	 * @return array Address 
	 */
	public function getAddress( $userId, $credential, $customerId= null)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			if( empty( $customerId)){
				$customerId = $userId; 
			}
			return $this->_order->getAddress( $customerId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Devuelve un array la info de una direccion 
	 * @param integer $userId
	 * @param string $credential
	 * @param integer $addressId
	 * @return array Address 
	 */
	public function getAddressInfo( $userId, $credential, $addressId)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getAddressInfo( $addressId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
	
	
	/**
	 * 
	 * Devuelve un array completo con todas las direcciones asociadas a un usuario 
	 * @param integer userId
	 * @param string Credential
	 * @param integer customerId
	 * @return array Address 
	 */
	public function getBookAddress( $userId, $credential, $customerId= null)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			if( empty( $customerId)){
				$customerId = $userId; 
			}
			return $this->_order->getBookAddress( $customerId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
		
	/**
	 * 
	 * Agrega una direccion asociada a un usuario
	 * @param integer userId
	 * @param string Credential
	 * @param mixed Address
	 * @return boolean true|false
	 */
	public function addAddress( $userId, $credential, $address)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->addAddress( $userId, $address );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
	
	/**
	 * 
	 * Establece el telefono de contacto para la orden
	 * @param integer userId
	 * @param string Credential
	 * @param string ContactPhone
	 * @return mixed true|false
	 */
	public function setContactPhone( $userId, $credential, $contactPhone )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->setContactPhone( $userId, $contactPhone );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Obtiene el telefono de contacto de la orden  
	 * @param integer userId
	 * @param string Credential
	 * @return string ContactPhone 
	 */
	public function getContactPhone( $userId, $credential)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getContactPhone( $userId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Obtiene el la direccion de envio del producto  
	 * @param integer userId
	 * @param string Credential
	 * @return string ShipAddress
	 */
	public function getShipAddress( $userId, $credential)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getShipAddress( $userId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}	
	
	/**
	 * 
	 * Obtiene el la direccion de despacho de boleta de la orden 
	 * @param integer userId
	 * @param string Credential
	 * @return string BillAddress
	 */
	public function getBillAddress( $userId, $credential)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getBillAddress( $userId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}	
	
	/**
	 * Retorna todas las ordenes cerradas de un cliente. 
	 * @param integer userId
	 * @param string Credential
	 * @return array Orders
	 */
	public function getOrderHistory( $userId, $credential )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getOrderHistory( $userId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Obtiene el total a pagar de la order 
	 * @param integer userId
	 * @param string Credential
	 * @return double Total
	 */
	public function getTotalAmount( $userId, $credential)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getTotalAmount($userId);
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
	
	/**
	 * 
	 * Obtiene el estado de la orden 
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @return string Status
	 */
	public function getStatus( $userId, $credential, $orderId)
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getStatus( $orderId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
	
	/**
	 * 
	 * Establece el estado la orden
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @param string Status
	 * @return mixed true|false
	 */
	public function setStatus( $userId, $credential, $orderId, $status )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->setStatus( $orderId, $status );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Cierra la orden Activa del cliente.
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @return boolean true|false
	 */
	public function closeOrder( $userId, $credential, $orderId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->closeOrder( $orderId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
	
	/**
	 * 
	 * Agrega un item a la orden. 
	 * Si existe un producto igual en la orden, le suma las cantidades. 
	 * Si la cantidad final es menor a 1 se borra el item de la orden
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @param mixed Line
 	 * @return Boolean True
	 */
	public function addOrderLine( $userId, $credential, $orderId, $line )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->addOrderLine( $orderId, $line );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}
	
	/**
	 * Agrega propiedades a las lineas de una orden
	 * @param integer UserId
	 * @param string Credential
	 * @param integer LineId
	 * @param mixed Properties
	 */
	public function addLineProperty( $userId, $credential, $lineId, $properties ) 
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->addOrderLine( $lineId, $properties );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * todas las propiedades de una linea
	 * @param integer userId
	 * @param string Credential
	 * @param integer LineId
	 * @return array Line
	 */
	public function getOrderLine( $userId, $credential, $lineId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getOrderLine( $lineId );
		} catch( Exception $e ) {
			throw new Ext_Exception( $e );
		}
	}

	/**
	 * 
	 * Devuelve las lineas de una orden  
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderID
	 * @return array lineModel
	 */
	public function getOrderLines( $userId, $credential, $orderId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getOrderLines( $orderId );
		} catch( Exception $e ){
			throw new Ext_Exception( $e );
		}
	}
	
	/**
	 * 
	 * Establece la direccion de cobro para la orden
	 * 
	 * @param integer userId
	 * @param string Credential
	 * @param integer AddressBillId
	 * @param integer $shippingMethodId 
	 * @return boolean true
	 */
	public function setBillAddress( $userId, $credential, $billAddressId, $shippingMethodId = null )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->setBillAddress( $userId, $billAddressId, $shippingMethodId );
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}
	
	/**
	 * 
	 * Establece la direccion de envio para la orden
	 * 
	 * @param integer userId
	 * @param string Credential
	 * @param integer AddressShipId
	 * @param integer $shippingMethodId
	 * @return boolean true
	 */
	public function setShipAddress( $userId, $credential, $shipAddressId, $shippingMethodId = null )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->setShipAddress( $userId,  $shipAddressId, $shippingMethodId);
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}

	/**
	 * 
	 * Establece el metodo de pago para la orden
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @param integer PaymentMethdId
	 * @return boolean true
	 */
	public function setPaymentMethod( $userId, $credential, $orderId, $paymentMethodId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->setPaymentMethod( $orderId, $paymentMethodId );
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}

	/**
	 * 
	 * Agrga propiedades a una orden 
	 * 
	 * @param integer userId
	 * @param string Credential
	 * @param mixed properties
	 * @return boolean true|false
	 */
	public function addOrderProperty($userId, $credential, $properties )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->addOrderProperty( $userId, $properties );
		} catch ( Execption $e ) {
			error_log( $e->getMessage());
			throw new Ext_Ext( $e );
		}
	}

	/**
	 * 
	 * (cacheable) Devuelve el listado de los metodos de pago
	 * @param integer userId
	 * @param string Credential
	 * @return array PaymentMethods
	 */
	public function getPaymentMethods( $userId, $credential )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->getPaymentMethods();
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}
		
	/**
	 * 
	 * Establece el tipo de envio de la orden
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @param integer ShippingMethodId
	 * @return boolean true
	 */
	public function setShippingMethod( $userId, $credential, $orderId, $shippingMethodId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->setShippingMethod( $orderId, $shippingMethodId );
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}
	
	/**
	 * 
	 * Establece que la orden se cobro
	 * @param integer userId
	 * @param string Credential
	 * @param integer OrderId
	 * @return mixed true|false
	 */
	public function payOrder( $userId, $credential, $orderId )
	{
		try{
			$this->_validateCredential( $userId, $credential );
			return $this->_order->payOrder( $orderId );
		}catch ( Execption $e ) {
			throw new Ext_Ext( $e );
		}
	}
	
	/**
	 * 
	 * Devuelve el Metodo de envio default para el sistema (cacheable)
	 * @return integer
	 */
	public function getShippingMethodDefault()
	{
		return $this->_config->Shipping->method->chileexpress;
	}

    /**
     * Recibe una orden y la envia al tracker
     *
     * @param integer userId
     * @param string credential
     * @param integer $idOrden
     * @return boolean true|false
     * @todo Flag para saber si factura o no en vez de esto pasar un json con 
     * Title y Author productDescription
     */
    public function trackOrder( $userId, $credential, $orderId )
    {
        return $this->_order->trackOrder( $orderId );
    }
}